define(["drawable"], function (Drawable) {

    var colliderCollisionListener = function (coll, stats) {

        var SIDE_NONE = -1;
        var SIDE_TOP = 0;
        var SIDE_RIGHT = 1;
        var SIDE_BOTTOM = 2;
        var SIDE_LEFT = 3;

        var statistics = stats;
        var collider = coll;
        var collidables = [];
        var sidePenetration = [0, 0, 0, 0]; // top, right, bottom, left

        this.registerCollidable = function (collidable) {
            collidables.push(collidable);
        };

        this.registerCollidableArray = function (collidableArray) {
            for (var i = 0; i < collidableArray.length; ++i) {
                collidables.push(collidableArray[i]);
            }
        };

        this.reset = function () {
            collidables.length = 0;
        };

        var getCollisionSide = function () {

            var index = 0;
            var min = sidePenetration[index];
            for (var i = 1; i < sidePenetration.length; ++i) {
                if (sidePenetration[i] < min) {
                    min = sidePenetration[i];
                    index = i;
                }
            }

            return index;
        };

        this.listen = function () {
            var collidable = null;

            // collision side only for collider

            for (var i = 0; i < collidables.length; ++i) {
                collider.collisionSide = collider.SIDE_NONE;
                collidable = collidables[i];

                if (!collidable.isCollidable) {
                    continue;
                }

                var dX = Math.abs(collider.getCenterX() - collidable.getCenterX());
                var dY = Math.abs(collider.getCenterY() - collidable.getCenterY());

                var pN = {
                    x: collider.getCenterX(),
                    y: collider.y
                };
                var pE = {
                    x: collider.x + collider.w,
                    y: collider.getCenterY()
                };
                var pS = {
                    x: collider.getCenterX(),
                    y: collider.y + collider.h
                };
                var pW = {
                    x: collider.x,
                    y: collider.getCenterY()
                };
                
                var collisionAngle = Math.atan(dX / dY);

                var collidableTop = collidable.y;
                var collidableRight = collidable.x + collidable.w;
                var collidableBottom = collidable.y + collidable.h;
                var collidableLeft = collidable.x;                

                if (collidableTop <= pN.y && pN.y <= collidableBottom && collidableLeft <= pN.x && pN.x <= collidableRight) {
                    collider.collisionSide = SIDE_TOP;
                } else if (collidableLeft <= pE.x && pE.x <= collidableRight && collidableTop <= pE.y && pE.y <= collidableBottom) {
                    collider.collisionSide = SIDE_RIGHT;
                } else if (collidableTop <= pS.y && pS.y <= collidableBottom && collidableLeft <= pS.x && pS.x <= collidableRight) {
                    collider.collisionSide = SIDE_BOTTOM;
                } else if (collidableLeft <= pW.x && pW.x <= collidableRight && collidableTop <= pW.y && pW.y <= collidableBottom) {
                    collider.collisionSide = SIDE_LEFT;
                }

                if (collider.collisionSide != SIDE_NONE) {
                    collider.collides(collidable);
                    collidable.collides(collider);
                    if (collidable.score !== undefined && collidable.score !== null) {
                        statistics.addScore(collidable.score);
                    }
                }
            }
        };
    };

    return colliderCollisionListener;
});